package com.sanbi.erp.api.util;


import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.printing.PDFPageable;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.PrintPDF;

import javax.imageio.ImageIO;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import java.awt.image.BufferedImage;
import java.awt.print.*;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Desc:
 * @Data: 2022/8/5 11:46
 * @Author: jxk
 */
@Slf4j
public class PdfUtil {
    /**
     * 创建一个pdf
     * @throws Exception
     */
    public static void createPDF() throws Exception {
        // 实例化 document
        Document document = new Document();
        // 生成文件
        String path = "c:/Users/ywszx/Desktop/wd/13.pdf";
        File file = new File(path);
        if (!file.exists()) {
            file.createNewFile();
        }
        PdfWriter.getInstance(document, new FileOutputStream( "c:/Users/ywszx/Desktop/wd/13.pdf"));
        // 打开 document
        document.open();
        // 添加文本 此处无法写入中文 TODO
        document.add(new Paragraph("ccc"));
        // 关闭 document
        document.close();
    }


    /**
     * 用模板生成pdf
     * @throws Exception
     */
    public static void createAllPdf(Map<String,String> map,String pdfTemplate,String fileName){
        //填充创建pdf
        PdfReader reader = null;
        PdfStamper stamp = null;
        try {
            // 设置字体
//            BaseFont bf = BaseFont.createFont("c:/Users/ywszx/Desktop/wd/sku1.pdf" , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            reader = new PdfReader(pdfTemplate);
            SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd");
            String times = simp.format(new Date()).trim();
            // 创建生成报告名称
//            String root = ServletActionContext.getRequest().getRealPath("/upload") + File.separator;
//            if (!new File(root).exists())
//                new File(root).mkdirs();
//            File deskFile = new File(root, times + ".pdf");
            stamp = new PdfStamper(reader, new FileOutputStream(fileName));
            //取出报表模板中的所有字段
            AcroFields form = stamp.getAcroFields();

            // 填充数据
//            form.addSubstitutionFont(bf);
            for(String key : map.keySet()){
                String value = map.get(key);
                form.setField(key,value);
            }
//            form.setField("skuName", "可口可乐");
//            form.setField("skuCode", "DH");
//            form.setField("shelve", "X 货架");
//            form.setField("skuNumber", "2");
//            form.setField("orderCreateTime", "2022");
//            List<String> skuInfo=new ArrayList<>();
            //报告生成日期
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
            String generationdate = dateformat.format(new Date());
            form.setField("generationdate", generationdate);
            stamp.setFormFlattening(true);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stamp != null) {
                try {
                    stamp.close();
                } catch (Exception e) {
                   log.error("pdf生成失败：",e);
                }

            }
            if (reader != null) {
                reader.close();
            }
        }
    }



    /**
     * 合并pdf文件
     * @param files 需要合并的文件
     * @param newfile 合并生成的文件
     * @return
     */
    public static void mergePdfFiles(String[] files, String newfile) {
        Document document = null;
        try {
            PdfReader pdfReader = new PdfReader(files[0]);
            document = new Document(pdfReader.getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));
            document.open();
            for (int i = 0; i < files.length; i++) {
                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }
            copy.close();
            pdfReader.close();
        } catch (Exception e) {
           log.error("合并失败：",e);
        } finally {
            if (document != null) document.close();
        }
    }

    /**
     * 合并pdf文件2
     * @param urls 需要合并的文件路径
     * @param newFile 合并生成的文件
     * @return
     */
    public static void mergeRemotePdfFiles(String[] urls, String newFile) {
        Document document = null;
        try {
            PdfReader pdfReader = new PdfReader(urls[0]);
            document = new Document(pdfReader.getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newFile));
            document.open();
            for (int i = 0; i < urls.length; i++) {
                PdfReader reader = new PdfReader(urls[i]);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }
            copy.close();
            pdfReader.close();
        } catch (Exception e) {
           log.error("合并失败：",e);
        } finally {
            if (document != null) document.close();
        }
    }

    public static void mergePdf(){
        try {
//            File file = new File("PATH");
//            PDDocument doc = PDDocument.load(file);
            PDFMergerUtility pdfMerger = new PDFMergerUtility();
            pdfMerger.addSource("c:/Users/ywszx/Desktop/wd/base64EncodeContent.pdf");
            pdfMerger.addSource("c:/Users/ywszx/Desktop/wd/sku.pdf");
            pdfMerger.setDestinationFileName("c:/Users/ywszx/Desktop/wd/merge7.pdf");
            pdfMerger.mergeDocuments(null);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 静默打印
     * @param filePath
     * @param printName
     */
    public static void printPDFBox(String filePath,String printName){
        try {
            PrintPDF.main(new String[]{
                    "-silentPrint",//静默打印
//                    "-password","abcde",//pdf打开密码
                    "-printerName",printName,//指定打印机名
                    "-orientation","portrait",//打印方向，三种可选auto|landscape|portrait
                    filePath//打印PDF文档的路径
            });
        } catch (Exception e) {
            log.error("打印异常：",e);
        }
    }

    /**
     *  打印方法1
     * pdfByte:需要打印的pdf字节数组
     * printName：打印机名称
     * copies：打印份数
     * duplex：是否双面打印
     */
    public static void print(String base64Str, String printName, int copies, boolean duplex) {
        try {
            //加载pdf文件对象
            PDDocument document = PDDocument.load(Base64.getDecoder().decode(base64Str));
            printPDFMethods(copies, duplex, document);
        } catch (Exception e) {
            log.error("请检查打印机是否正常连接!", e);
        }
    }

    /**
     *  打印方法2
     * filePath:需要打印的pdf文件路径
     * copies：打印份数
     * duplex：是否双面打印
     */
    public static void printPDF(String fileName, int copies, boolean duplex) {
        try {
            //加载pdf文件对象
            PDDocument document = PDDocument.load(new File(fileName));
            printPDFMethods(copies, duplex, document);
        } catch (Exception e) {
            log.error("请检查打印机是否正常连接!",e);
        }
    }

    /**
     *  打印方法3
     * in:需要打印的pdf文件流
     * copies：打印份数
     * duplex：是否双面打印
     */
    public static void printPDFFile(InputStream in, int copies, boolean duplex) {
        try {
            //加载pdf文件对象
            PDDocument document = PDDocument.load(in);
            //创建打印任务
            printPDFMethods(copies, duplex, document);
        } catch (Exception e) {
            log.error("请检查打印机是否正常连接!",e);
        }
    }

    private static void printPDFMethods(int copies, boolean duplex, PDDocument document) throws PrinterException {
        //创建打印任务
        PrinterJob job = PrinterJob.getPrinterJob();
        // 遍历所有打印机的名称
        for (PrintService ps : PrinterJob.lookupPrintServices()) {
            String psName = ps.getName();
            //选用指定打印机
            //使用默认打印机
            PrintService service = PrintServiceLookup.lookupDefaultPrintService();
            String name = service.getName();
            if (psName.equals(name) || psName.contains(name)) {
                job.setPrintService(ps);
                break;
            }
        }
        job.setPageable(new PDFPageable(document));
        Paper paper = new Paper();
        // 设置打印纸张大小
        paper.setSize(598, 842);
        // 设置打印位置 坐标
        paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
        PageFormat pageFormat = new PageFormat();
        pageFormat.setPaper(paper);
//            pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);//横向 从右向左
//            pageFormat.setOrientation(PageFormat.PORTRAIT);//横向 从左向右
        pageFormat.setOrientation(PageFormat.PORTRAIT);//纵向
        Book book = new Book();
        book.append(new PDFPrintable(document, Scaling.ACTUAL_SIZE), pageFormat, 2);
        job.setPageable(book);
        //打印份数
        job.setCopies(copies);
        if (duplex) {//双面打印
            PrintRequestAttributeSet printSet = new HashPrintRequestAttributeSet();
            printSet.add(Sides.DUPLEX);
            //执行打印操作
            job.print(printSet);
        } else {//单面打印
            job.print();
        }
    }

    /**
     * pdf转jpg
     */
    public static void pdf2jdp(String pdfFile,String jdgFile){
        try {
            //加载现有 PDF 文档
            PDDocument document = PDDocument.load(new File(pdfFile));
            //实例化 PDFRenderer 类
            PDFRenderer renderer = new PDFRenderer(document);
            //从 PDF 文档渲染图像
            BufferedImage image = renderer.renderImage(0);
            //将图像写入文件
            ImageIO.write(image,"JPEG",new File(jdgFile));
            //关闭文档
            document.close();
        } catch (IOException e) {
            log.error("转换异常",e);
        }
    }

    /**
     * 获取可以打印服务列表
     * @return
     */
    public static List<String> findPrintName(){
        List<String> list = new ArrayList<>();
        HashPrintRequestAttributeSet requestAttributeSet = new HashPrintRequestAttributeSet();
        DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
        //查找所有的可用的打印服务
        PrintService[] printService = PrintServiceLookup.lookupPrintServices(flavor, requestAttributeSet);
        if (printService == null || printService.length == 0) {
            log.info("打印获取失败，未找到可用打印机，请检查。");
        }
        if (printService != null) {
            for (PrintService print : printService) {
                list.add(print.getName());
            }
        }

        //默认打印机
//        PrintService service = PrintServiceLookup.lookupDefaultPrintService();
//        String name = service.getName();
        return list;
    }

    /**
     * 用模板生成pdf2
     * @throws Exception
     */
    public static void createTemplatePdf(Map<String,List<String>> map1,Map<String,String> map2,String pdfTemplate,String fileName){
        //填充创建pdf
        PdfReader reader = null;
        PdfStamper stamp = null;
        try {
            reader = new PdfReader(pdfTemplate);
            SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd");
            String times = simp.format(new Date()).trim();
            //创建生成报告名称
            stamp = new PdfStamper(reader, new FileOutputStream(fileName));
            //取出报表模板中的所有字段
            AcroFields form = stamp.getAcroFields();

            // 填充数据
//            form.addSubstitutionFont(bf);
            for(String key : map1.keySet()){
                List<String> value = map1.get(key);
                form.setField(key,StringUtils.join(value," / ").replace("/","\r\n"));
            }
            String expressNo = map2.get("expressNo");
            form.setField("expressNo",expressNo);

            //报告生成日期
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
            String generationdate = dateformat.format(new Date());
            form.setField("generationdate", generationdate);
            stamp.setFormFlattening(true);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stamp != null) {
                try {
                    stamp.close();
                } catch (Exception e) {
                    log.error("pdf生成失败：",e);
                }
            }
            if (reader != null) {
                reader.close();
            }
        }
    }

    /**
     * 在pdf文档中插入图片
     * @param fileName
     * @param imageFile
     * @param newFile
     */
    public static void pdfInsertImg(String fileName,String imageFile,String newFile){

        try {
            //1,加载现有文档
            PDDocument document = PDDocument.load(new File(fileName));
            //2，检索页面
            PDPage page = document.getPage(0);
            //3，创建PDImageXObject对象
            PDImageXObject pdImage = PDImageXObject.createFromFile(imageFile, document);
            //4,准备内容流
            PDPageContentStream contentStream = new PDPageContentStream(document, page);
            //5, 在pdf文档中绘制对象
            contentStream.drawImage(pdImage,598,842);
            //6,关闭PDPageContentStream
            contentStream.close();
            //7,保存文档
            document.save(newFile);
            //8,关闭文档
            document.close();
        } catch (IOException e) {
            log.error("图片插入失败：",e);
        }
    }


    /**
     * 合并方法2
     * @param file1
     * @param file2
     * @param newFile
     */
    public static void MergePDFs(String file1,String file2,String newFile){
            //Instantiating PDFMergerUtility class
            PDFMergerUtility PDFmerger = new PDFMergerUtility();
            //Setting the destination file
            PDFmerger.setDestinationFileName(newFile);
            //adding the source files
        try {
            PDFmerger.addSource(file1);
            PDFmerger.addSource(file2);
            //Merging the two documents
            PDFmerger.mergeDocuments();
            System.out.println("Documents merged");
        } catch (Exception e) {
            log.error("");
        }


    }

    public static void main(String[] args) {
       String filePath="c:/Users/ywszx/Desktop/wd/";
        //        createPDF();
        Map<String,List<String>> map1=new HashMap<>();
        Map<String,String> map2=new HashMap<>();
////        map.put("skuCode","DH7787557U");
////        map.put("shelve","X 货架 J 列 H行");
//
        List<String> skuInfo=new ArrayList<>();
        skuInfo.add("1*1-sss");
        skuInfo.add("2*2-aaa");
        skuInfo.add("3*4-bbb");
//
//
//
       // map.put("skuInfo", StringUtils.join(skuInfo," / ").replace("/","\r\n"));
      //  map.put("listBox", skuInfo);
        map1.put("skuInfo", skuInfo);
        map2.put("expressNo","123456222222222");
//        createTemplatePdf(map1,map2,filePath+"PDFTemplate.pdf",filePath+"sku3.pdf");
//        mergePdfFiles(new String[]{"/imile/OX220802170009436.pdf", "skuInfo2.pdf"}, "merge11.pdf");
        MergePDFs(filePath+"/imileSO220830193248289.pdf",filePath+"skuInfoSO220830193248289.pdf",filePath+"merge1.pdf");
//        pdf2jdp();

//                printPDFBox("c:/Users/ywszx/Desktop/wd/createOrderB2c.pdf","HP Laser MFP 131 133 135-138");
//        print(base64ToFileByte(""),"",1,false);
//       findPrintName();

//        printPDF("http://192.168.1.117:9091/group1/2022/09/01/202209011119073m1iv6.pdf?download=0",1,false);
//        mergePdf();

    }
}
